package cn.buk.qms.task;

import cn.buk.qms.service.*;
import cn.buk.tms.bill.service.BillCheckService;
import cn.buk.tms.car.service.RentalCarService;
import cn.buk.tms.flight.service.AutoTicketService;
import cn.buk.tms.hotel.service.HotelOrderService;
import cn.buk.common.util.DateUtil;
import cn.buk.tms.vas.service.VasOrderService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;


/**
 * 定时任务
 *
 * @author yfdai
 */
@Profile({"dev"})
@Component
public class PnrTaskDev {

  @Autowired
  public PnrTaskDev(@Value("${server_id}") int serverId,
                    @Value("${owner_enterprise_id}") int ownerId,
                    BillService billService,
                    BillCheckService billCheckService,
                    BillAutoTaskService billAutoTaskService,
                    FlightOrderService flightOrderService,
                    HotelOrderService hotelOrderService,
                    VasOrderService vasOrderService,
                    RentalCarService rentalCarService,
                    ReportService reportService,
                    EnterpriseService enterpriseService,
                    EnterpriseStatService enterpriseStatService,
                    AutoTicketService autoTicketService) {
    this.serverId = serverId;
    this.ownerId = ownerId;
    this.billService = billService;
    this.billCheckService = billCheckService;
    this.billAutoTaskService = billAutoTaskService;
    this.flightOrderService = flightOrderService;
    this.hotelOrderService = hotelOrderService;
    this.vasOrderService = vasOrderService;
    this.rentalCarService = rentalCarService;
    this.reportService = reportService;
    this.enterpriseService = enterpriseService;
    this.enterpriseStatService = enterpriseStatService;
    this.autoTicketService = autoTicketService;
  }

  private static final int SERVER_MAIN = 1;
  private static final int SERVER_SECONDARY = 2;
  private static final int SERVER_THIRD = 3;

  private static final Logger logger = LogManager.getLogger(PnrTaskDev.class);

  private final int serverId;

  private final int ownerId;

  private String getAgentName() {
    return "system-" + serverId;
  }

  private final BillService billService;
  private final BillCheckService billCheckService;
  private final BillAutoTaskService billAutoTaskService;
  private final FlightOrderService flightOrderService;
  private final HotelOrderService hotelOrderService;
  private final RentalCarService rentalCarService;
  private final VasOrderService vasOrderService;
  private final ReportService reportService;
  private final EnterpriseService enterpriseService;
  private final EnterpriseStatService enterpriseStatService;
  private final AutoTicketService autoTicketService;


  /**
   * .
   * 将账单金额记录到企业应付款中
   */
  @Scheduled(cron = "0 30 19 * * *")
  public void syncBillInfo2AmountBalance() {
    if (serverId != SERVER_MAIN) {
      return;
    }

    final Date startTicket = DateUtil.getCurDateTime();

    // 将BillInfo(t301)中新来的账单的金额统计到客户应付款中
    billCheckService.syncBillInfo2Balance();

    //        billService.syncBillTicketCount(); // 修改ticket_count
    //        billService.syncBillOp1(); // 修改op1

    long elapse = DateUtil.getCurDateTime().getTime() - startTicket.getTime();
    logger.debug("syncBillInfo2AmountBalance elapsed: " + elapse + " ms.");
  }

  @Scheduled(cron = "0 0/15 0 * * *")
  public void syncBillInfoAirlines() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }

    billCheckService.syncBillAirlines();
    billCheckService.checkFlightOrderImportedStatus(getAgentName());
  }

  /**
   * 将账单的销账状态反馈到订单中
   */
  @Async
  @Scheduled(cron = "0 * * * * *")
  public void syncBillPaidStatus() {
    if (serverId != SERVER_MAIN) {
      return;
    }

    final Date startTicket = DateUtil.getCurDateTime();

    final int max = 5000;

    billAutoTaskService.autoSyncBillPaid2FlightOrder(getAgentName(), max);
    billAutoTaskService.autoSyncBillPaid2VasOrder(getAgentName(), max);

    billAutoTaskService.autoSyncBillPaid2RefundOrder(getAgentName(), max);
    billAutoTaskService.autoSyncBillPaid2ChangeOrder(getAgentName(), max);

    billAutoTaskService.autoSyncBillPaid2HotelOrder(getAgentName(), max);
    billAutoTaskService.autoSyncBillPaid2TrainOrder(getAgentName(), max);

    long elapse = DateUtil.getCurDateTime().getTime() - startTicket.getTime();
    logger.debug("syncBillPaidStatus elapsed: " + elapse + " ms.");
  }

  @Scheduled(cron = "0 0/5 22,23 * * *")
  public void updateBillRefundTicketPnrNo() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }
    billService.updateBillRefundTicketPnrNo(getAgentName());
  }


  /**
   * 检查账单中的订单日期.
   */
  @Scheduled(cron = "0 0/30 * * * *")
  public void autoCheckBillOrderDate() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    billService.autoUpdateBillVas(getAgentName());
  }


  /**
   * 礼拜一早上8点30分统计一次，六个月内未支付金额最多的头10名，按每月
   */
  @Scheduled(cron = "0 30 8 * * 1")
  public void autoAlertUnpaidMonthlyStats() {
    if (serverId != SERVER_MAIN) {
      return;
    }

    final Date startTicket = DateUtil.getCurDateTime();

    reportService.autoAlertMonthlyUnpaidTop10();

    long elapse = DateUtil.getCurDateTime().getTime() - startTicket.getTime();
    logger.info("autoAlertUnpaidMonthlyStats elapsed: " + elapse + " ms.");
  }

  /**
   * 每30分钟统计是否有订单需要处理
   */
  @Scheduled(cron = "0 0 0 * * 1-5")
  public void autoAlertHotelOrderStatus() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    //酒店订单
    hotelOrderService.autoAlertHotelOrderStatus();

  }


  /**
   * 每天晚上9点3统计一次，3个月内没有账单的客户
   * <p>
   * cron一般是6个部分或是7个部分：如下所示：
   * 1. Seconds （秒）
   * 2. Minutes （分）
   * 3. Hours （时）
   * 4. Day-of-Month （天）
   * 5. Month （月） Month(月) ：可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示；
   * 6. Day-of-Week （周） Day-of-Week(*每周*)*：*可以用数字1-7表示（1 ＝ 星期日）或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示；
   * 7. Year (年 可选字段)
   */
  @Scheduled(cron = "0 0 21 * * 1")
  public void autoAlertNoBusinessCustomer() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    final Date startTicket = DateUtil.getCurDateTime();

    reportService.autoAlertNoBusinessCustomer(this.ownerId, 100);

    long elapse = DateUtil.getCurDateTime().getTime() - startTicket.getTime();
    logger.info("autoAlertNoBusinessCustomer elapsed: " + elapse + " ms.");
  }

  /**
   * 定时禁用近半年没有采购记录的企业客户
   */
  @Scheduled(cron = "0 0 0 * * *")
  public void autoDisableCustomers() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    final Date startTicket = DateUtil.getCurDateTime();

    reportService.autoDisableCustomers(this.ownerId, 200, getAgentName());
    reportService.autoDisableSuppliers(this.ownerId, 200, getAgentName());

    long elapse = DateUtil.getCurDateTime().getTime() - startTicket.getTime();
    logger.info("autoDisableCustomers elapsed: " + elapse + " ms.");
  }

  /**
   * 每天早上0点30分，把机票订单中的乘机人信息导入到Passenger(t601)中
   */
  @Scheduled(cron = "0 30 0 * * *")
  public void importPassenger() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }

    try {
      enterpriseService.importPassengers(5);
    } catch (Exception ex) {

    }

  }

  /**
   * 导入手机号
   * 每天早上0点30分，把机票订单中的乘机人信息导入到Passenger(t601)中
   */
  @Scheduled(cron = "0 0 0 * * *")
  public void importPassengerMobile() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      enterpriseService.importPassengerMobiles(ownerId, getAgentName(), 55);
    } catch (Exception ignored) {
    }
  }


  /**
   * 清理重复的
   */
  @Scheduled(cron = "0 30 6 * * *")
  public void cleanDuplicatePassenger() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }
    enterpriseService.cleanDuplicatePassenger(5);
  }


  /**
   * 将线上订单同步到线下订单进行处理
   */
  @Scheduled(cron = "0 0/5 0 * * *")
  public void syncFlightOrderOnline2Offline() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }

    //自动修改火车票账单中psg_count的数值
    billCheckService.autoCheckTrainBillPsgCount(getAgentName());
  }


  /**
   * 每30秒查找一次需要自动BSP出票的
   */
  @Scheduled(cron = "0/30 0 * * * *")
  public void checkAutoPrintTickets() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }

    autoTicketService.checkAutoTicketOrder(5, getAgentName());
  }


  /**
   * 检查需要提交到VAAS的第三方订单
   */
  @Scheduled(cron = "0 0/5 0 * * *")
  public void checkVaasOrder() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    vasOrderService.checkVaasOrders(5, getAgentName());
//    vasOrderService.checkVaasOrders(24, getAgentName());
  }


  /**
   * 携程国际比价（暂停）
   */
  @Scheduled(cron = "0 * * * * *")
  public void bijiaIntlFare() {
    if (serverId != SERVER_SECONDARY) {
      return;
    }

//    intlOwPolicyService.monitorOwPolicy();
//    intlRtPolicyService.monitorRtPolicy();
  }

  @Scheduled(cron = "0 0 5 * * *")
  public void refreshCustomerRecency() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    enterpriseService.refreshCustomerRecency();
  }

  @Scheduled(cron = "0 0/5 0 * * *")
  public void refreshPassengerRecency() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    enterpriseStatService.refreshPassengerRecency();
  }

  @Scheduled(cron = "0 0 0 * * *")
  public void refreshSupplierFrequency() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    enterpriseService.refreshSupplierFrequency();
  }

  //  @Scheduled(cron = "0 0/10 * * * *")
  @Scheduled(cron = "0 1 0 * * *")
  public void saveBasicData2Redis() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    //把静态数据放到redis中方便微服务调用
    enterpriseService.saveBasicData2Redis();
  }

  /**
   * 每30秒查找一次需要自动生成编码和验价的
   */
  @Scheduled(cron = "0/30 * * * * *")
  public void checkFlightOrderPrice() {
    if (serverId != SERVER_THIRD) {
      return;
    }

//    etermService.checkFlightOrderPrice(5, getAgentName());
//    etermService.checkFlightOrderPrice(ownerId, getAgentName());
//    hotelOrderService.checkHotelOrderPrice(ownerId, getAgentName());
//  }
  }

  /**
   * 每分钟查找一次需要自动分配审批人的订单
   */
  @Scheduled(cron = "0 0 * * * *")
  public void checkOrderNeedApprover() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    flightOrderService.checkFlightOrderNeedApprover(ownerId, getAgentName());
    hotelOrderService.checkHotelOrderNeedApprover(ownerId, getAgentName());
    rentalCarService.checkRentalCarOrderNeedApprover(ownerId, getAgentName());
  }

  /**
   * 每分钟查找一次需要校验是否违反企业差旅规定的订单
   */
  @Scheduled(cron = "0 0 0 * * *")
  public void checkFlightOrderMeetPolicy() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    hotelOrderService.checkHotelOrderCityId(ownerId, getAgentName());

    flightOrderService.checkFlightOrderMeetPolicy(ownerId, getAgentName());
    hotelOrderService.checkHotelOrderMeetPolicy(ownerId, getAgentName());
    rentalCarService.checkRentalCarOrderMeetPolicy(ownerId, getAgentName());
  }

  /**
   * 每天检查机票业务规则
   */
  @Scheduled(cron = "0 * * * * *")
  public void validateFlightBusinessRule() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      flightOrderService.validateFlightBusinessRule(ownerId, getAgentName());
//      changeOrderService.recheckChangeOrderDetrInfo(ownerId, getAgentName());
    } catch (Exception ex) {
      ex.printStackTrace();
      logger.error(ex.getMessage());
    }
  }

  /**
   * 检查机票订单的显示状态
   */
  @Scheduled(cron = "0 0/15 * * * *")
  public void checkFlightOrderShowStatus() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      flightOrderService.checkFlightOrderShowStatus(ownerId, getAgentName());
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  /**
   * 定时生成每日审核任务
   */
  @Scheduled(cron = "0 0/30 * * * *")
  public void createDailyAuditTask() {
    if (serverId != SERVER_THIRD) {
      return;
    }

    try {
      enterpriseService.createDailyAuditTask(ownerId, getAgentName());
    } catch (Exception ex) {
      ex.printStackTrace();
      logger.error(ex.getMessage());
    }
  }

}
